
ActiveRecord::Base.send :alias_method, :pre_constant_attributes_with_quotes, :attributes_with_quotes

class ActiveRecord::Base
  class << self
    # Attributes listed as constant can be set for a new record, but will be ignored in database updates afterwards. 
    def attr_constant(*attributes) 
      write_inheritable_array("attr_constant", attributes - (constant_attributes || [])) 
    end

    # Returns an array of all the attributes that have been specified as constant. 
    def constant_attributes 
      read_inheritable_attribute("attr_constant") 
    end
  end


  # Removes attributes which have been marked as constant. 
  def remove_constant_attributes(attributes) 
    unless self.class.constant_attributes.nil? 
      attributes.reject { |key, value| self.class.constant_attributes.include?(key.gsub(/\(.+/,"").intern) } 
    else 
      attributes 
    end 
  end

  # Return a copy of the attributes hash with all constant values removed if this is not the first save
  def attributes_with_quotes(include_primary_key = true, include_constant_attributes = true)
    quoted = pre_constant_attributes_with_quotes(include_primary_key)
    include_constant_attributes ? quoted : remove_constant_attributes(quoted)
  end

  # replace previous update with one of our own.  this most likely isn't very compatible with any 
  # other releases than 1.2.3 (in other words YMMV and it isn't my fault if this breaks your shit)
  def update
    connection.update(
    "UPDATE #{self.class.table_name} " +
    "SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false, false))} " +
    "WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}",
    "#{self.class.name} Update"
    )
  end
end
